using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace PeDALS.Tools.AZ.PSTArchive
{
    public partial class PSTArchiveUI : Form
    {
        bool mblnProfile = false;
        private iPlug mipExtract;
        private List<LogEntry> mlleExtractionLog = new List<LogEntry>();
        private LogEntryDisplay mledLogDisplay;

        public PSTArchiveUI()
        {
            this.components = new System.ComponentModel.Container();
            InitializeComponent();
        }

        private void PSTArchiveUI_Load(object sender, EventArgs e)
        {
            this.Text = string.Format("{0} - v. {1} {2}", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductName, FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion, FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion);
            sslStatus.Text = string.Format("{0}", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).LegalCopyright);
            List<FileInfo> lfiFileList = Utilities.GetPluginFileList(Environment.CurrentDirectory);
            List<iPlug> lsPlugs = new List<iPlug>();
            foreach (FileInfo fiFile in lfiFileList)
            {
                List<string> lsPlugins = Utilities.GetPlugins(fiFile.FullName);
                foreach (string strPlugin in lsPlugins)
                {
                    iPlug ipPlug = Utilities.GetPlugin(fiFile.FullName, strPlugin);
                    lsPlugs.Add(ipPlug);
                }
            }
            cboEngine.DataSource = lsPlugs;
            cboEngine.DisplayMember = "Description";
            SetControls(true);
        }

        private void btnExtract_Click(object sender, EventArgs e)
        {
            SetControls(false);
            mipExtract = (iPlug)cboEngine.SelectedItem;
            mipExtract.ExecutionProgress += new ExecutionProgressEventHandler(mipExtract_ExecutionProgress);
            mipExtract.ExecutionComplete += new ExecutionCompleteEventHandler(mipExtract_ExecutionComplete);
            mipExtract.ExecutionException += new ExecutionExceptionEventHandler(mipExtract_ExecutionException);
            mipExtract.Execute(lblPSTFile.Text, lblOutputFolder.Text, txtProfile.Text, true, true);
        }

        private void btnPSTFile_Click(object sender, EventArgs e)
        {
            ofdSelectFile.Title = "Select PST File";
            ofdSelectFile.Multiselect = false;
            ofdSelectFile.DefaultExt = "*.pst";
            ofdSelectFile.Filter = "Outlook PST Files (*.pst)|*.pst";
            ofdSelectFile.ShowDialog();
            lblPSTFile.Text = ofdSelectFile.FileName;
            SetControls(true);
        }

        private void btnSelectOutputFolder_Click(object sender, EventArgs e)
        {
            fbdSelectFolder.RootFolder = Environment.SpecialFolder.MyComputer;
            fbdSelectFolder.ShowNewFolderButton = true;
            fbdSelectFolder.ShowDialog();
            lblOutputFolder.Text = fbdSelectFolder.SelectedPath;
            SetControls(true);
        }

        private void cboEngine_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (mblnProfile != ((iPlug)cboEngine.SelectedItem).ProfileRequired)
            {
                mblnProfile = ((iPlug)cboEngine.SelectedItem).ProfileRequired;
                txtProfile.Text = txtProfile.Text.Length == 0 ? ((iPlug)cboEngine.SelectedItem).DefaultProfile : txtProfile.Text;
                MoveControls(mblnProfile);
            }
        }

        private void mipExtract_ExecutionProgress(object sender, ProgressEventArgs e)
        {
            sslStatus.Text = string.Format("{0}", e.Status);
            Trace.Write(sslStatus.Text);
            sspbItemProgress.Value = e.CurrentItemProgress;
            sspbTaskProgress.Value = e.CurrentTaskProgress;
            sslCounters.Text = string.Format("{0} item{1}, {2} folder{3} processed", e.CurrentItemCompletedCount, e.CurrentItemCompletedCount == 1 ? "" : "s", e.CurrentTaskCompletedCount, e.CurrentTaskCompletedCount == 1 ? "" : "s");
            mlleExtractionLog.Add(new LogEntry(e.EntryType, string.Format("{0}{1}", e.Status, e.CurrentItemCompletedCount > 0 || e.CurrentTaskCompletedCount > 0 ? string.Format(" {0} item{1}, {2} folder{3} processed", e.CurrentItemCompletedCount, e.CurrentItemCompletedCount == 1 ? "" : "s", e.CurrentTaskCompletedCount, e.CurrentTaskCompletedCount == 1 ? "" : "s"): "")));
            UpdateLogDisplay(false);
        }

        private void mipExtract_ExecutionComplete(object sender, CompleteEventArgs e)
        {
            if (e.Error != null)
            {
                sslStatus.ForeColor = Color.Red;
                sslStatus.Text = string.Format(e.Error.Message);
                Trace.Write(sslStatus.Text);
            }
            else
            {
                sslStatus.ForeColor = Color.Black;
                sslStatus.Text = string.Format("{0} {1} item{2}, {3} folder{4} processed in {5}{6}{7:##}.{8:000} seconds", e.Status, e.ItemCount, e.ItemCount == 1 ? "" : "s", e.TaskCount, e.TaskCount == 1 ? "" : "s", e.ElapsedTime.Hours > 0 ? string.Format("{0} hour{1} ", e.ElapsedTime.Hours, e.ElapsedTime.Hours == 1 ? "" : "s") : "", e.ElapsedTime.Hours > 0 || e.ElapsedTime.Minutes > 0 ? string.Format("{6} minute{7} ", e.ElapsedTime.Minutes, e.ElapsedTime.Minutes == 1 ? "" : "s") : "", e.ElapsedTime.Seconds, e.ElapsedTime.Milliseconds);
                Trace.Write(sslStatus.Text);
                mipExtract.ExecutionProgress -= new ExecutionProgressEventHandler(mipExtract_ExecutionProgress);
                mipExtract.ExecutionComplete -= new ExecutionCompleteEventHandler(mipExtract_ExecutionComplete);
                mipExtract.ExecutionException -= new ExecutionExceptionEventHandler(mipExtract_ExecutionException);
                mipExtract = null;
                mlleExtractionLog.Add(new LogEntry(e.EntryType, string.Format("{0} {1} item{2}, {3} folder{4} processed in {5}{6}{7:##}.{8:000} seconds", e.Status, e.ItemCount, e.ItemCount == 1 ? "" : "s", e.TaskCount, e.TaskCount == 1 ? "" : "s", e.ElapsedTime.Hours > 0 ? string.Format("{0} hour{1} ", e.ElapsedTime.Hours, e.ElapsedTime.Hours == 1 ? "" : "s") : "", e.ElapsedTime.Hours > 0 || e.ElapsedTime.Minutes > 0 ? string.Format("{6} minute{7} ", e.ElapsedTime.Minutes, e.ElapsedTime.Minutes == 1 ? "" : "s") : "", e.ElapsedTime.Seconds, e.ElapsedTime.Milliseconds)));
                SetControls(true);
            }
            UpdateLogDisplay(true);
        }

        private void mipExtract_ExecutionException(object sender, ProgressEventArgs e)
        {
            sslStatus.ForeColor = Color.Red;
            sslStatus.Text = string.Format("{0}", e.Status);
            Trace.Write(sslStatus.Text);
            sspbItemProgress.Value = e.ProgressPercentage;
            mlleExtractionLog.Add(new LogEntry(e.EntryType, e.Status));
            UpdateLogDisplay(false);
        }

        private void mledLogDisplay_Disposed(object sender, EventArgs e)
        {
            mledLogDisplay.Disposed -= new EventHandler(mledLogDisplay_Disposed);
            mledLogDisplay = null;
            mlleExtractionLog.Clear();
        }

        private void SetControls(bool blnEnabled)
        {
            sslStatus.AutoSize = blnEnabled;
            sslStatus.Width = blnEnabled ? 0 : 200;
            btnExtract.Enabled = blnEnabled & lblOutputFolder.Text.Length > 0 & lblPSTFile.Text.Length > 0;
            btnPSTFile.Enabled = blnEnabled;
            btnSelectOutputFolder.Enabled = blnEnabled;
            txtProfile.Enabled = blnEnabled;
            cboEngine.Enabled = blnEnabled;
            sspbItemProgress.Visible = !blnEnabled;
            sspbItemProgress.Value = 0;
            sspbTaskProgress.Visible = !blnEnabled;
            sspbTaskProgress.Value = 0;
            sslCounters.Visible = !blnEnabled;
            sslCounters.Text = "";
        }

        private void MoveControls(bool blnEnabled)
        {
            Size sMinimumFormSize = new Size(this.MinimumSize.Width, this.MinimumSize.Height);
            sMinimumFormSize.Height += blnEnabled ? 29 : -29;
            this.MinimumSize = sMinimumFormSize;
            if (this.Height < 242 && this.Height != this.MinimumSize.Height) this.Height += blnEnabled ? 29 : -29;
            btnExtract.Top += blnEnabled ? 29 : -29;
            btnPSTFile.Top += blnEnabled ? 29 : -29;
            btnSelectOutputFolder.Top += blnEnabled ? 29 : -29;
            lblLabelSelectOutputFolder.Top += blnEnabled ? 29 : -29;
            lblLabelSelectProfile.Visible = blnEnabled;
            lblLabelSelectPSTFile.Top += blnEnabled ? 29 : -29;
            lblOutputFolder.Top += blnEnabled ? 29 : -29;
            lblPSTFile.Top += blnEnabled ? 29 : -29;
            txtProfile.Visible = blnEnabled;
        }

        private void UpdateLogDisplay(bool blnSave)
        {
            if (mledLogDisplay == null)
            {
                mledLogDisplay = new LogEntryDisplay(lblOutputFolder.Text);
                mledLogDisplay.Disposed += new EventHandler(mledLogDisplay_Disposed);
            }
            mledLogDisplay.ExtractionLog = mlleExtractionLog;
            mledLogDisplay.Save = blnSave;
            if (!mledLogDisplay.Visible)
            {
                mledLogDisplay.Show();
            }
        }
    }
}